/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is ART OWL API.
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2009.
 * All Rights Reserved.
 *
 * The ART OWL API were developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about the ART OWL API can be obtained at 
 * http://art.uniroma2.it/owlart
 *
 */

package it.uniroma2.art.owlart.testutils;

import static org.junit.Assert.*;

import it.uniroma2.art.owlart.model.ARTNode;
import it.uniroma2.art.owlart.model.ARTResource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import com.google.common.collect.Iterators;
import com.google.common.collect.ListMultimap;

public class AssertOntologies {

	/**
	 * checks that the elements in the ordered collection actualCollection are the same of those in
	 * expectedCollection
	 * 
	 * @param expectedCollection
	 * @param actualCollection
	 */
	static public void assertSameOrderedCollections(List<?> expectedCollection, List<?> actualCollection) {
		if (actualCollection == null)
			throw new AssertionError(
					"there is no element for actual collection while at least one was expected");
		Object x[] = expectedCollection.toArray();
		Object y[] = actualCollection.toArray();

		if (x.length != y.length)
			throw new AssertionError(
					"the number of element is not the same between expectedCollection and actualCollection");

		for (int i = 0; i < actualCollection.size(); i++)
			if (!x[i].equals(y[i]))
				throw new AssertionError("element: " + x
						+ " is expected, though not present in the actual collection (" + y + ")");
	}

	/**
	 * checks that the elements in the unordered collection actualCollection are the same of those in
	 * expectedCollection
	 * 
	 * @param expectedCollection
	 * @param actualCollection
	 */
	static public void assertSameUnorderedCollections(Collection<?> expectedCollection,
			Collection<?> actualCollection) {
		if (actualCollection == null)
			throw new AssertionError(
					"there is no element for actual collection while at least one was expected");
		for (Object toBeRemoved : expectedCollection) {
			boolean removed = actualCollection.remove(toBeRemoved);
			if (removed == false) {
				throw new AssertionError("element: " + toBeRemoved
						+ " is expected, though not present in the actual collection");
			}
		}
		if (!actualCollection.isEmpty())
			throw new AssertionError(
					"the actual collection has more objects than the expected one. This is the surplus: "
							+ actualCollection);
	}

	/**
	 * checks that the elements in the unordered collection actualCollection are the same of those in
	 * expectedCollection
	 * 
	 * @param <T>
	 * 
	 * @param expectedCollection
	 * @param actualCollection
	 */
	static public <T> void assertSameUnorderedIterators(Collection<? extends T> expectedCollection,
			Iterator<? extends T> actualIterator) {
		if (actualIterator == null)
			throw new AssertionError("the Iterator is null");
		Collection<T> actualCollection = new ArrayList<T>();
		Iterators.addAll(actualCollection, actualIterator);
		assertSameUnorderedCollections(expectedCollection, actualCollection);
	}

	/**
	 * given a multimap testNGMap which is filled with nodes associated to given graphs, it checks if the
	 * unordered list of nodes in <code>testNGMap</code> associated to the key <code>ng</code> is equal to the
	 * list determined by the vararg parameter <code>expectedNodes</code>
	 * 
	 * @param testNGMap
	 * @param ng
	 * @param expectedNodes
	 */
	static public void assertSameUnorderedResources(ListMultimap<ARTResource, ARTNode> testNGMap,
			ARTResource ng, ARTNode... expectedNodes) {
		Collection<? extends ARTNode> actualNodes = testNGMap.get(ng);
		if (actualNodes == null)
			throw new AssertionError("there is no element for named graph: " + ng
					+ " while at least one was expected");
		assertSameUnorderedCollections(Arrays.asList(expectedNodes), actualNodes);
	}

	static public void assertContains(String msg, Iterator<?> it, Object elem) {
		assertContains(msg, true, it, elem);
	}

	static public void assertNotContains(String msg, Iterator<?> it, Object elem) {
		assertContains(msg, false, it, elem);
	}

	static public void assertContains(String msg, boolean condition, Iterator<?> it, Object elem) {
		if (!condition == Iterators.contains(it, elem))
			fail(msg);
	}

	static public void failedOntUpdate() {
		throw new AssertionError("failed to update the ontology ");
	}

	static public void failedOntAccess() {
		throw new AssertionError("failed to access the ontology ");
	}

}
